package com.klarna.ondemand.crypto;
import android.content.Context;
import android.os.Build;
import android.util.Base64;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.robolectric.Robolectric;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import static org.assertj.core.api.Assertions.assertThat;
@Ignore
public abstract class CryptoBaseTest {
protected CryptoBase crypto;
protected abstract CryptoBase getTestSubject(Context context) throws Exception;
protected abstract int getTestSdkVersion();
//region Before each
@Before
public void beforeEach() throws Exception {
Robolectric.Reflection.setFinalStaticField(Build.VERSION.class,
"SDK_INT", getTestSdkVersion());
android.content.Context context = Robolectric.application.getApplicationContext();
crypto = getTestSubject(context);
}
//endregion
//region Instance methods
@Test
public void getPublicKeyBase64Str_shouldReturnSameKeyOnTwoConsecutiveCalls () {
String publicKeyA = crypto.getPublicKeyBase64Str();
String publicKeyB = crypto.getPublicKeyBase64Str();
assertThat(publicKeyA)
.isNotEmpty()
.isEqualTo(publicKeyB);
}
/*
TODO: https://jira.internal.machines/jira/browse/IACO-1036 - Support latest Android Studio (fix unit tests)
(JUnit4 makes it almost impossible to write the test for this use-case)
@Test
public void sign_shouldSignMessageWithInternalPrivateKey () throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {
mockStatic(CryptoBase.class);
when(CryptoBase.sign("data", crypto.getPrivateKey())).thenReturn("my_signature");
assertThat(crypto.sign("data")).isEqualTo("my_signature");
}
*/
//endregion
//region Class methods
@Test
public void sign_shouldReturnSameSignOnTwoIdenticalCalls() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
PrivateKey privateKey = generatePrivateKey();
String signA = CryptoBase.sign("my_message", privateKey);
String signB = CryptoBase.sign("my_message", privateKey);
assertThat(signA)
.isNotEmpty()
.isEqualTo(signB);
}
@Test
public void sign_shouldReturnDifferentSignWhenProvidedWithDifferentMessages() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
PrivateKey privateKey = generatePrivateKey();
String signA = CryptoBase.sign("my_message_A", privateKey);
String signB = CryptoBase.sign("my_message_B", privateKey);
assertThat(signA)
.isNotEmpty()
.isNotEqualTo(signB);
assertThat(signB).isNotEmpty();
}
@Test
public void sign_shouldReturnDifferentSignWhenProvidedWithDifferentPrivateKeys() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
String signA = CryptoBase.sign("my_message", generatePrivateKey());
String signB = CryptoBase.sign("my_message", generatePrivateKey());
assertThat(signA)
.isNotEmpty()
.isNotEqualTo(signB);
assertThat(signB).isNotEmpty();
}
@Test
public void sign_shouldCaclculateAValidSignature() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, InvalidKeySpecException {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decode("MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAskcFcO+vuYAQfRjCGkhZXMGlrtpbJZRq9y0SJi2DlKo2Ph58Ni9j6mN4DVKdSSJhuR/myNzXmszLzZIgq1AwpQIDAQABAkA641rYw1O4YqUPrW3wYJWkHhMsftQ8xZnPrAOiuMYOBN5jJ1pKBXiy3nHxBCiSWAJY+kWSWzbY1zzecBtmbCDBAiEA1lrU0Uhk3H7v7qyZPWIgu2pHYi+/W17c3jsl/NgHQfMCIQDU6dea1HCfWcU31cW/wShhzXd4h1H6AqEmRIEGnCLRBwIhAINNAC9x+NZXqwC4GOXQxdwHLdKnDMAbS4+VC5/ldAyhAiEAs4/PhMWbgdisyi0gzFpz2x/0nRLK4SXskKB/jHqLpmsCICTcahC8Xm8EFD/kxkDpI2oMZuWa2ghvZ1zuSMpnfkgE", Base64.DEFAULT));
KeyFactory keyFact = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFact.generatePrivate(pkcs8EncodedKeySpec);
assertThat(CryptoBase.sign("my_data", privateKey)).isEqualTo("n8PEnZ5s5Cn39Jx2nMRf+cTbw7YIw5ak0HBEQJUl4mX/rMjo1SQe/56elt95c5H9TydbEcmvDeDt\n2SpHXylNDA==\n");
}
//endregion
//region Helper methods
private PrivateKey generatePrivateKey() throws NoSuchAlgorithmException {
return SharedPreferencesCryptoImpl.generateKeyPair().getPrivate();
}
//endregion
}